﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using System.Data;
using FactoryJournalDB;
using InterFaceFinance;


namespace Journals
{
 
    public class clsJournal:IJournal
    {

        
       
        private IJournalDB iJournalDB;
        
     
        private string _strReceiptNumber;
        private DateTime _dtJournalDate;
        private string _strDescription;
        private int _intAccId;
        private int _intAccPeriod;
        private int _companyid;
        private clsTransactions objTransactions = new clsTransactions();
        private clsTransaction objTransaction = new clsTransaction();
        private clsChartofAccount objChartAccount = new clsChartofAccount();


        public int CompanyID
        {
            set { _companyid = value; }
            get { return _companyid;}
        }

        public string ReceiptNumber
        {
           
            set
            {

                _strReceiptNumber = value;
            
            }
            get
            {

                return _strReceiptNumber;
            }
        }


        public string Description
        {
            set
            {

                _strDescription = value;

            }
            get
            {
                return _strDescription;
            }
        }

        public int AccType
        {
            get { return _intAccId ; }
            set { _intAccId = value; }
        }

        public int AccPeriod
        {
            get { return _intAccPeriod; }
            set { _intAccPeriod = value; }
        }

  
        public DateTime JournalDate
        {
            set
            {
                
                _dtJournalDate = value;
            } 
            get
            {
                return _dtJournalDate;
            }
        }

        public bool ISFinancialYear(DateTime Jdate)
        {
            
            return false;
        }

        public void addTransaction(double dblAmount, int intDebitCredit, int intChartofAccount)
        {
            bool isChartofAccount;

            isChartofAccount = objChartAccount.ISControlChartofAccount(intChartofAccount,this.CompanyID);
            if (isChartofAccount == true)
            {
                objTransactions.AddTransaction(intChartofAccount, intDebitCredit, dblAmount);
            }
            else
            {
                throw new Exception("Invalid Chart of Account");
            }
              
        }

        public void Update()
        {
           
            int intJournalid;
            bool _isDebitCreditOK;
            iJournalDB = FJournalDB.JournalDB();
           _isDebitCreditOK= objTransactions.DeBitCreDit_Chk();

           if (_isDebitCreditOK == true)
           {

               JournalValidation();
               intJournalid = iJournalDB.InsertJournals(this);

               foreach (clsTransaction objTransaction in objTransactions)
               {

                   objTransaction.Update(intJournalid);
               }

           }
           else
           {
               throw new Exception("Debit Credit is not Equal");
           }

        }
        public object LoadAccounts()
        {
            iJournalDB = FJournalDB.JournalDB();
            return iJournalDB.LoadDBAccounts(this.CompanyID);
           
        }

        public object LoadJournal(int JournalId)
        {
            iJournalDB = FJournalDB.JournalDB();
            return iJournalDB.LoadDBJournal(JournalId);
        }




        public void SetJournalUI(int JournalId)
        {
            DataSet ds;
            iJournalDB = FJournalDB.JournalDB();
            ds =(DataSet) iJournalDB.EditDBJournal(JournalId);
            if (ds.Tables[0].Rows.Count != 0)
            {
                ReceiptNumber = ds.Tables[0].Rows[0]["ReceiptNumber"].ToString();
                JournalDate = Convert.ToDateTime(ds.Tables[0].Rows[0]["JournalDate"].ToString());
                Description = ds.Tables[0].Rows[0]["Description"].ToString();
            }
            else
            {
                throw new Exception("Error inloading records");
            }
        }

        public void JournalValidation()
        {
            if(this.ReceiptNumber == "")
            {
                throw new Exception("Enter the Receipt Number");
            }

            
            

            if (this.JournalDate.ToString() == "")
            {
                throw new Exception("Enter the Journal Date");
            }
            else
            {
                DataSet ds;
                iJournalDB = FJournalDB.JournalDB();
                string currdates=this.JournalDate.ToString();
                ds = (DataSet)iJournalDB.LoadFinancialYear(currdates, this.CompanyID);
                if (ds.Tables[0].Rows.Count != 0)
                {

                    if (ds.Tables[0].Rows[0]["is_active"].ToString() == Convert.ToString("Y"))
                    {
                        if (Convert.ToDateTime(ds.Tables[0].Rows[0]["start_date"].ToString()) <= this.JournalDate &&
                            Convert.ToDateTime(ds.Tables[0].Rows[0]["end_date"].ToString()) >= this.JournalDate)
                        {
                            //do nothing
                        }
                        else
                        {
                            throw new Exception("Date Should be between Financial Year");
                        }
                    }
                    else
                    {
                        throw new Exception("Financial year is not active");
                    }

                }

            }

            if(this.Description.ToString() == "")
            {
                throw new Exception("Enter the Description");
            }

            if(this.AccPeriod.ToString() == "")
            {
                throw new Exception("Enter the Account Period");
            }

        }


        


       
    }
    
    public class clsTransaction:ITransaction
    {
        private int _intDebitCredit;
        private double _dblAmount;
        private int _intChartofAccount;
        clsTransactions objTransactions = new clsTransactions();
        
        private IJournalDB iJournalDB;
       
        public int ChartofAccount
        {
            set
            {
              
                _intChartofAccount = value;

            }
            get
            {
                return _intChartofAccount;
            }
        }
        
        public int DebitCredit
        {
            set
            {
                _intDebitCredit = value;
            }
            get
            {
                return _intDebitCredit;
            }
        }

        
        public double TransactionAmount
        {
            set
            {
                _dblAmount = value;


            }
            get
            {
                return _dblAmount;
            }
        }

     

        public void Update(int intJournalId)
        {

            iJournalDB = FJournalDB.JournalDB();
            TransactionValidation();
            iJournalDB.InsertJournalTransaction(intJournalId, _dblAmount, _intDebitCredit, _intChartofAccount);

        }

        public void RemoveTransactionList(int ListID)
        {
            objTransactions.RemoveAt(ListID);
        }


        public void TransactionValidation()
        {
            if (this.ChartofAccount.ToString() == "")
            {
                throw new Exception("Enter the ChartofAccount");
            }

            if (this.DebitCredit.ToString() == "")
            {
                throw new Exception("Enter the Debit/Credit");
            }

            if (this.TransactionAmount.ToString() == "")
            {
                throw new Exception("Enter the Transaction Amount");
            }

            

        }
        

    }
    public class clsTransactions :CollectionBase
    {
        internal void AddTransaction(int intChartofAccountid, int intDebitCredit, double dblAmount)
        {
            
            clsTransaction objTransaction = new clsTransaction();
            objTransaction.ChartofAccount = intChartofAccountid;
            objTransaction.DebitCredit = intDebitCredit;
            objTransaction.TransactionAmount = dblAmount;
           

     
                List.Add(objTransaction);
           
        
        }

        public bool DeBitCreDit_Chk()
        {
          
            double _sumamount1 = 0;
            double _sumamount2 = 0;

            if (this.Count > 0)
            {
                foreach (clsTransaction objTransac in this)
                {

                    if (objTransac.DebitCredit == 1)
                    {
                        _sumamount1 += objTransac.TransactionAmount;
                    }
                    if (objTransac.DebitCredit == 0)
                    {
                        _sumamount2 += objTransac.TransactionAmount;
                    }
              
                }
            }//List Count
            
            
            if (_sumamount1 == _sumamount2)
            {
                return true;
            }

           
          
           
            return false;
        }
               
    }



    public class clsChartofAccount:IChartofAccounts
    {

        
        private IJournalDB iJournalDB;
        private int _accountnumber;
        private string _description;
        private int _chartaccID;
        private int _companyid;
        private int _acctypeID;



        public int AccountNumber
        {
            set { _accountnumber = value; }
            get { return _accountnumber; }
        }


        public string Description
        {
            set { _description = value; }
            get { return _description; }
        }


        public int ChartofAccID
        {
            set { _chartaccID = value; }
            get { return _chartaccID; }
        }


        public int AccountTypeID
        {
            set { _acctypeID = value; }
            get { return _acctypeID; }
        }


        public int Company_id
        {
            set { _companyid = value; }
            get { return _companyid; }
        }



        public object LoadChartofAccount(int CompanyId)
        {
            iJournalDB = FJournalDB.JournalDB();
            return iJournalDB.LoadChartofAccount(CompanyId);

        }

        public bool ISControlChartofAccount(int ChartofAccountID,int CompanyId)
        {
            DataSet ds;
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.EditChartofAccount(ChartofAccountID,0,CompanyId);
            if (ds.Tables[0].Rows.Count != 0)
            {
               DataSet ds1;
               ds1 = (DataSet)iJournalDB.EditChartofAccount(0,Convert.ToInt16(ds.Tables[0].Rows[0]["id"].ToString()),CompanyId);

               if (ds1.Tables[0].Rows.Count == 0)
               {
                   return true;
               }
               else
               {
                   return false;
               }

            }
            return false;

        }


        public void InsertChartofAccounts(bool IsControlofAccount)
        {

            if (IsControlofAccount == true)
            {
                int ChartAccID;
                ChartAccID = iJournalDB.InsertChartofAccountDB(this,true);
            }
            if (IsControlofAccount == false)
            {
                int ChartAccID;
                ChartAccID = iJournalDB.InsertChartofAccountDB(this,false);
            }

        }



    }


    public class ClosingAccounts:ICloseAccount
    {


        private DateTime _dtstartdate;
        private DateTime _dtenddate;
        private string _isactive;
        private int _companyid;

        
        private IJournalDB iJournalDB;


        public int Company_id
        {
            set { _companyid = value; }
            get { return _companyid; }
        }


        public DateTime StartDate
        {
            set
            {

                _dtstartdate = value;
            }
            get
            {
                return _dtstartdate;
            }
        }


        public DateTime EndDate
        {
            set
            {

                _dtenddate = value;
            }
            get
            {
                return _dtenddate;
            }
        }

      

        public void CloseAccount(int CompanyID)
        {
            DataSet ds;
            int Insertid = 0;
            string currdate = Convert.ToString(System.DateTime.Now);
            iJournalDB = FJournalDB.JournalDB();
            int year_id=0;


            ds = (DataSet)iJournalDB.LoadFinancialYear(currdate,CompanyID);

            foreach (DataRow theRow in ds.Tables["financialYear"].Rows)
            {
                year_id = Convert.ToInt16(theRow["year_id"]);

            }
              int Updateid= (int)iJournalDB.UpdateFinancialYear(year_id, this);

              if (Updateid != 0)
              {
                  Insertid = (int)iJournalDB.UpdateFinancialYear(0, this);

              }

              if (Insertid == 0)
              {
                  throw new Exception("Error in closing accounts");
              }

        }
    }




    public class clsTrialBalance:ITrialBalance
    {

        
        private IJournalDB iJournalDB;

        public double getDebitTransaction(int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            double getDebitamt = 0;
            ds = (DataSet)iJournalDB.LoadControlofAccounts(CompanyId);

            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {

                getDebitamt += getDebitTransactionIndividual(Convert.ToInt16(theRow["id"]),CompanyId);

            }

            return getDebitamt;
        }


        public double getCreditTransaction(int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            double getDebitamt = 0;
            ds = (DataSet)iJournalDB.LoadControlofAccounts(CompanyId);

            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {

                getDebitamt += getCreditTransactionIndividual(Convert.ToInt16(theRow["id"]),CompanyId);

            }

            return getDebitamt;
        }


        public double getDebitTransactionIndividual(int ChartofAccountID, int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.LoadSingleControlofAccounts(ChartofAccountID,CompanyId);
            double amt=0;
           
            List<double> DebitCredit = new List<double>();

           
            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {

                if (Convert.ToInt16(theRow["DebitCredit"]) == 0)
                {
                    amt += amt + Convert.ToDouble(theRow["Amount"]);
                }
               

            }

            return amt;

         


        }




        public double getCreditTransactionIndividual(int ChartofAccountID, int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.LoadSingleControlofAccounts(ChartofAccountID,CompanyId);
            double amt = 0;

            List<double> DebitCredit = new List<double>();


            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {

                if (Convert.ToInt16(theRow["DebitCredit"]) == 1)
                {
                    amt += amt + Convert.ToDouble(theRow["Amount"]);
                }


            }

            return amt;




        }


        public ArrayList getDebitCreditTotalBalance(int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            double getDebitamt = 0;
            double getCreditamt = 0;
            ArrayList armain = new ArrayList();
            ds = (DataSet)iJournalDB.LoadControlofAccounts(CompanyId);


            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {
                ArrayList ar = new ArrayList();
                ar = getDebitCreditBalanceIndividual(Convert.ToInt16(theRow["id"]),CompanyId);
                getDebitamt +=Convert.ToDouble(ar[0]);
                
            }

            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {
                ArrayList ar = new ArrayList();
                ar = getDebitCreditBalanceIndividual(Convert.ToInt16(theRow["id"]),CompanyId);
                getCreditamt += Convert.ToDouble(ar[1]);

            }

            armain.Add(getDebitamt);
            armain.Add(getCreditamt);

            return armain;
        }

        public ArrayList getDebitCreditBalanceIndividual(int ChartofAccountID, int CompanyId)
        {
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.LoadSingleControlofAccounts(ChartofAccountID,CompanyId);
            double amt = 0;
            double amt2 = 0;
            ArrayList arlist = new ArrayList();


            List<double> DebitCredit = new List<double>();


            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {
                if (Convert.ToInt16(theRow["DebitCredit"]) == 0)
                {
                    amt += amt + Convert.ToDouble(theRow["Amount"]);
                }


                if (Convert.ToInt16(theRow["DebitCredit"]) == 1)
                {
                    amt2 += amt2 + Convert.ToDouble(theRow["Amount"]);
                }

            }


            if (amt > amt2)
            {
                double newamt = 0;
                newamt = amt - amt2;
                arlist.Add(newamt);
                arlist.Add(0);
            }
            else if (amt < amt2)
            {
                double newamt = 0;
                newamt = amt2 - amt;
                arlist.Add(0);
                arlist.Add(newamt);
            }
            else if (amt == amt2)
            {
                double newamt = 0;
                newamt = amt - amt2;
                arlist.Add(0);
                arlist.Add(0);
            }
            else
            {
                arlist.Add(0);
                arlist.Add(0);
            }
            
            return arlist;




        }




    }

    public class clsProfitLoss:IProfitLoss
    {
        
        private IJournalDB iJournalDB;
        clsTrialBalance objTrialBalance = new clsTrialBalance();



        public ArrayList getDebitSide(int ChartofAccID, int CompanyId)
        {
            ArrayList armain = new ArrayList();
          
            iJournalDB = FJournalDB.JournalDB();

           
            double getDebitamt = 0;

           
                ArrayList ar = new ArrayList();
                ar = objTrialBalance.getDebitCreditBalanceIndividual(ChartofAccID,CompanyId);
                getDebitamt += Convert.ToDouble(ar[0]);
            

            armain.Add(getDebitamt);
            return armain;

        }



        public ArrayList getCreditSide(int ChartofAccID, int CompanyId)
        {
            ArrayList armain = new ArrayList();

            iJournalDB = FJournalDB.JournalDB();


            double getCreditamt = 0;


            ArrayList ar = new ArrayList();
            ar = objTrialBalance.getDebitCreditBalanceIndividual(ChartofAccID,CompanyId);
            getCreditamt += Convert.ToDouble(ar[1]);


            armain.Add(getCreditamt);
            return armain;

        }

        public ArrayList getProfitLoss(int CompanyId)
        {
            ArrayList armain = new ArrayList();
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.LoadControlofAccounts_ProfitLoss(CompanyId);
            double getDebitamt = 0;
            double getCreditamt = 0;
            double getProfit = 0;

            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {
                ArrayList ar = new ArrayList();
                ArrayList ar2 = new ArrayList();

                ar = getDebitSide(Convert.ToInt16(theRow["id"]),CompanyId);
                ar2 = getCreditSide(Convert.ToInt16(theRow["id"]),CompanyId);
                getDebitamt += Convert.ToDouble(ar[0]);
                getCreditamt += Convert.ToDouble(ar2[0]);

            }

            if(getDebitamt > getCreditamt)
            {
                getProfit = getDebitamt - getCreditamt;
            }
            else if (getDebitamt < getCreditamt)
            {
                getProfit = getCreditamt - getDebitamt;
            }
            else
            {
                getProfit = getCreditamt - getDebitamt;
            }

            armain.Add(getProfit);
           
            return armain;
        }

    }



    public class clsBalanceSheet:IBalanceSheet
    {

        
        private IJournalDB iJournalDB;
        clsTrialBalance objTrialBalance = new clsTrialBalance();




        public ArrayList getDebitSide(int ChartofAccID, int CompanyId)
        {
            ArrayList armain = new ArrayList();

            iJournalDB = FJournalDB.JournalDB();


            double getDebitamt = 0;


            ArrayList ar = new ArrayList();
            ar = objTrialBalance.getDebitCreditBalanceIndividual(ChartofAccID,CompanyId);
            getDebitamt += Convert.ToDouble(ar[0]);


            armain.Add(getDebitamt);
            return armain;

        }



        public ArrayList getCreditSide(int ChartofAccID, int CompanyId)
        {
            ArrayList armain = new ArrayList();

            iJournalDB = FJournalDB.JournalDB();


            double getCreditamt = 0;


            ArrayList ar = new ArrayList();
            ar = objTrialBalance.getDebitCreditBalanceIndividual(ChartofAccID,CompanyId);
            getCreditamt += Convert.ToDouble(ar[1]);


            armain.Add(getCreditamt);
            return armain;

        }



        public ArrayList getBalanceSheet(int CompanyId)
        {
            ArrayList armain = new ArrayList();
            DataSet ds = new DataSet();
            iJournalDB = FJournalDB.JournalDB();
            ds = (DataSet)iJournalDB.LoadControlofAccounts_BalanceSheet(CompanyId);
            double getDebitamt = 0;
            double getCreditamt = 0;
            double getProfit = 0;

            foreach (DataRow theRow in ds.Tables["ChartofAccounts"].Rows)
            {
                ArrayList ar = new ArrayList();
                ArrayList ar2 = new ArrayList();

                ar = getDebitSide(Convert.ToInt16(theRow["id"]),CompanyId);
                ar2 = getCreditSide(Convert.ToInt16(theRow["id"]),CompanyId);

                getDebitamt += Convert.ToDouble(ar[0]);
                getCreditamt += Convert.ToDouble(ar2[0]);

            }

            if (getDebitamt > getCreditamt)
            {
                getProfit = getDebitamt - getCreditamt;
            }
            else if (getDebitamt < getCreditamt)
            {
                getProfit = getCreditamt - getDebitamt;
            }
            else
            {
                getProfit = getCreditamt - getDebitamt;
            }

            armain.Add(getProfit);

            return armain;
        }


    }

    
}
